package de.lmu.ifi.pst.uwejsf.framework;

import java.util.Map;

import javax.script.ScriptContext;
import javax.script.ScriptEngine;

import org.apache.commons.beanutils.PropertyUtils;

public class OGNLGuardHandler implements GuardHandler {

	private Expression expression;

	@Override
	public boolean checkCondition(ExpressionContextProvider contextProvider) {
		// return true as fallback!
		if (expression == null)
			return true;
		if (expression.getExpression() == null)
			return true;

		ScriptEngine engine = contextProvider.getScriptEngineByName("ognl");
		Map<String, Object> beans = contextProvider.getManagedBeans();
		String usedContentInLink = expression.getContentInLink();
		Object contextBean = null;
		if (expression.getContextBeanName() != null)
			contextBean = beans.get(expression.getContextBeanName());
		Object contextObject = contextBean;
		if (usedContentInLink != null && contextBean != null) {
			try {
				contextObject = PropertyUtils.getProperty(contextBean,
						"content_" + usedContentInLink);
			} catch (Exception e) {
				throw new NavigationException("Couldn't get direct content "
						+ usedContentInLink + " for bean "
						+ expression.getContextBeanName(), e);
			}
		}

		ScriptContext scriptContext = contextProvider
				.createScriptContext(contextObject);
		Object result = null;
		try {
			result = engine.eval(expression.getExpression(), scriptContext);
		} catch (Exception e) {
			throw new NavigationException("Couldn't evaluate OGNL script: "
					+ expression.getExpression(), e);
		}
		if (!(result instanceof Boolean))
			throw new NavigationException(
					"OGNL script for guard didn't evaluate to Boolean: "
							+ expression.getExpression());
		return (Boolean) result;
	}

	@Override
	public Expression getExpression() {
		return expression;
	}

	@Override
	public void setExpression(Expression expression) {
		this.expression = expression;

	}

}
